package com.yhx.security.guangfa;

import cfca.sadk.algorithm.sm2.SM2PrivateKey;
import cfca.sadk.algorithm.sm2.SM2PublicKey;
import cfca.sadk.cgb.toolkit.BASE64Toolkit;
import cfca.sadk.cgb.toolkit.SM2Toolkit;
import cfca.sadk.cgb.toolkit.SM3Toolkit;
import cfca.sadk.cgb.toolkit.SM4Toolkit;
import cfca.sadk.lib.crypto.bcsoft.BCSoftSM2;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.PublicKey;

public class SM2SignUtil {
	public static final int BUFFSIZE = 10240;
	private static final String PVKFILE=".pvk";
	private static final String PUKFILE=".puk";
	public static boolean verifilyFile(String outfilePath,String keyPath,String signStr) throws Exception {
		boolean fila = false;
		//��ǩ�ļ�
		try {
		 SM2Toolkit tool = new SM2Toolkit();
		 SM2PublicKey sm2PublicKey =   (SM2PublicKey) tool.SM2BuildPublicKey(BASE64Toolkit.encode(readKey(keyPath)));
		 byte[] hash = SM3Toolkit.SM3HashFile(sm2PublicKey, outfilePath);
		 fila =  tool.SM2VerifyHash(sm2PublicKey, hash, BASE64Toolkit.decode(signStr));
		 
		}catch (Exception e) {
			throw new Exception("�ļ���ǩʧ��", e);
		}
		 
		return fila;
	} 
	
	public static String signString(PrivateKey privateKey,byte[] srcBytes,String encoding) throws Exception{
		String signValue = null;
		try{
			SM2Toolkit sm2Tool = new SM2Toolkit();

			SM2PrivateKey sm2PrivateKey = (SM2PrivateKey) privateKey;
			
			signValue=BASE64Toolkit.encode(sm2Tool.SM2Sign(sm2PrivateKey, srcBytes));
			//LOGGER.info("ǩ��ԭ��:"+srcStr);
		}catch(Exception e){
			throw new Exception("ǩ������",e);
		}
		return signValue;
	}
	
	/**
	 * ʹ������˽Կ���ļ�����ǩ��
	 * 
	 * @param filePath
	 * @return
	 * @throws Exception
	 */
	public static String sm2SignFile(String filePath,String privateKeyPath) throws Exception {
				
		SM2Toolkit tool = new SM2Toolkit();
		byte[] privateByte = readKey(privateKeyPath);
		SM2PrivateKey sm2PrivateKey = (SM2PrivateKey) tool.SM2BuildPrivateKey(BASE64Toolkit.encode(privateByte));
		byte[] hash = SM3Toolkit.SM3HashFile(sm2PrivateKey.getSM2PublicKey(),
				filePath);
		String signValue = BASE64Toolkit.encode(BCSoftSM2.sign(hash,
				sm2PrivateKey.dBigInteger(), true));
		return signValue;
	}
	
	/**
	 * ��ȡ��Կ
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	public static byte[] readKey(String filePath) throws IOException {
		if (filePath == null) {
			throw new IllegalArgumentException("Illegal Argument: filePath");
		}
		byte abyte0[];
		try (
			FileInputStream crls = new FileInputStream(filePath);
				){
			byte out[] = new byte[crls.available()];
			byte buffer[] = new byte[BUFFSIZE];
			int rLength;
			for (int offset = 0; (rLength = crls.read(buffer, 0, buffer.length)) != -1; offset += rLength) {
				System.arraycopy(buffer, 0, out, offset, rLength);
			}
			abyte0 = out;
		} catch (IOException e) {
			throw e;
		}
		return abyte0;
	}
	
	/**
	 * �����ļ�
	 * @param key
	 * @param inFile
	 * @param outFile
	 * @return
	 * @throws Exception 
	 */
	public static boolean SM4DecryptFile(String key,final String inFile, final String outFile) throws Exception{
		SM4Toolkit toolkit=new SM4Toolkit();
		boolean result=false;
		toolkit.SM4Init(key.getBytes(), key.getBytes());
		result=toolkit.SM4DecryptFile(inFile, outFile);
		return result;
	}
	
	/**
	 * ˽Կ����
	 * @param privateKey �̻�˽Կ
	 * @param encString ��������Կ
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptString(PrivateKey privateKey,String encString) throws Exception{	
		byte[] decryptResult=null;
		try {
			SM2Toolkit sm2Tool = new SM2Toolkit();
			
			SM2PrivateKey sm2PrivateKey = (SM2PrivateKey)privateKey;
			
			decryptResult =sm2Tool.SM2DecryptData(sm2PrivateKey, BASE64Toolkit.decode(encString));		
		} catch (Exception e) {
//			LOGGER.error("˽Կ����ʧ��");
			throw e;
		}
		return decryptResult;
	}
	
	/**
	 * ��ȡ˽Կ
	 * @param keyPath
	 * @return
	 * @throws Exception
	 */
	public static SM2PrivateKey buildPrivateKey(String keyPath) throws Exception {
		if(!keyPath.endsWith(PVKFILE)) {
			keyPath+=PVKFILE;
		}
		byte[] privateByte = readKey(keyPath);
		SM2Toolkit sm2Tool = new SM2Toolkit();
		SM2PrivateKey sm2PrivateKey = (SM2PrivateKey)sm2Tool.SM2BuildPrivateKey(BASE64Toolkit.encode(privateByte));
		return sm2PrivateKey;
	}
	
	/**
	 * ��ȡ��Կ
	 * @param keyPath
	 * @return
	 * @throws Exception
	 */
	public static SM2PublicKey buildPublicKey(String keyPath) throws Exception {
		if(!keyPath.endsWith(PUKFILE)) {
			keyPath+=PUKFILE;
		}
		byte[] publicByte = SM2SignUtil.readKey(keyPath);
		SM2Toolkit sm2Tool = new SM2Toolkit();
		SM2PublicKey sm2PublicKey = (SM2PublicKey)sm2Tool.SM2BuildPublicKey(BASE64Toolkit.encode(publicByte));
		return sm2PublicKey;
	}
	
	public static byte[] encrypt(PublicKey publicKey,byte[] needEncryptData) throws Exception{			
		byte[] encryptResult = null;
		try {
			SM2Toolkit sm2Tool = new SM2Toolkit();
			
			SM2PublicKey sm2MerPublicKey=(SM2PublicKey)publicKey;

			encryptResult=sm2Tool.SM2EncryptData(sm2MerPublicKey, needEncryptData);
		} catch (Exception e) {
			throw e;
		}
		return encryptResult;
	}



}
